package org.custom.spring.boot.security.filters;

import cn.hutool.core.util.StrUtil;
import org.custom.spring.boot.security.config.security.HttpAuthenticationEntryPoint;
import org.custom.spring.boot.security.constant.SecurityConstant;
import org.custom.spring.boot.security.filters.abstracts.AbstractUnityCommonFilter;
import org.custom.spring.boot.security.service.ApproveService;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static org.custom.spring.boot.security.constant.SecurityConstant.TOKEN_LOGO;

/**
 * 用户身份认证拦截器
 *
 * @author LiKun
 * @date 2021/11/8 18:29
 */
@Component("authenticationFilter")
public class AuthenticationFilter extends AbstractUnityCommonFilter {
    private static final int LENGTH = TOKEN_LOGO.length();

    @Resource
    private ApproveService approveService;
    @Resource
    private HttpAuthenticationEntryPoint httpAuthenticationEntryPoint;

    @Override
    protected boolean requestFilterLogicalProcess(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException {
        // 请求是否被允许继续向下执行
        boolean requestAllowed2Proceed = true;
        // 获取请求的 Token 数据信息
        final String header = request.getHeader(SecurityConstant.HEADER);

        // 判断请求头信息中是否存在有效的Token令牌
        if (StrUtil.isNotEmpty(header) && header.startsWith(TOKEN_LOGO)) {
            try {
                approveService.authenticate(header.substring(LENGTH));                   // 解析认证Token令牌
            } catch (AuthenticationException exception) {                                // 处理认证过程中可能抛出的异常信息
                requestAllowed2Proceed = false;
                httpAuthenticationEntryPoint.commence(request, response, exception);
            }
        }

        return requestAllowed2Proceed;
    }
}
